home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / cgazv5n4.arc / TXT2WP51.C < prev    next >
C/C++ Source or Header  |  1991-09-23  |  10KB  |  266 lines

  1. /*---- TXT2WP51.C ------------------------- Listing 2 -----
  2.  *  Convert ASCII text files to WordPerfect 5.1
  3.  *  by Andrew Binstock, v. 1.3
  4.  *
  5.  *  Verified for Borland C/C++, Microsoft 6.00A
  6.  *
  7.  *  Cpoyright 1991, Andrew Binstock. May be used freely if 
  8.  *      authorship and publication are acknowledged.
  9.  *
  10.  *  Usage: TXT2WP51 infile outfile
  11.  *-------------------------------------------------------*/
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <ctype.h>
  16. #include <conio.h>
  17.  
  18. #include "wpprefix.h"
  19.  
  20. FILE *fin, *fout;
  21. struct wp_prefix prefix;   /* from the wpprefix.h header */
  22. struct wp_addl_prefix addl_prefix;
  23. struct wp_packet_index packet;
  24.  
  25. void main ( int argc, char *argv[] )
  26. {
  27.     int last_char_out;
  28.  
  29.     WORD  data_array [4];
  30.  
  31.     if ( argc != 3 )
  32.     {
  33.         fputs ( "Invalid file specification. Usage:\n", stderr );
  34.         fputs ( "\n\tTXT2WP51 infile outfile\n\n", stderr );
  35.         fputs ( "infile = textfile, outfile = WordPerfect file",
  36.                     stderr );
  37.         exit ( 3 );
  38.     }
  39.  
  40.     if (( fin = fopen ( argv[1], "rb" )) == NULL )
  41.     {
  42.         fprintf ( stderr, "Unable to open: %s\n", argv[1] );
  43.         exit ( 4 );
  44.     }
  45.  
  46.     /*---------------------------------------------------------
  47.      * Before overwriting output file, let's make sure
  48.      *-------------------------------------------------------*/
  49.  
  50.     if (( fout = fopen ( argv[2], "rb" )) != NULL )
  51.     {
  52.         int yes_no;
  53.  
  54.         fclose ( fout );
  55.  
  56.         fprintf ( stderr, "\n%s exists. Overwrite? (Y/N) .\b",
  57.                     argv[2] );
  58.         yes_no = getch ();
  59.         if ( yes_no != 'Y' && yes_no != 'y' )
  60.              exit ( 5 );
  61.     }
  62.  
  63.     fout = fopen ( argv[2], "wb" );
  64.  
  65.     /*---------------------------------------------------------
  66.      * Is it already a WordPerfect file?  If so, get out.
  67.      *-------------------------------------------------------*/
  68.  
  69.     fread ( &prefix, sizeof ( struct wp_prefix ), 1, fin );
  70.  
  71.     if ( prefix.id[0] == -1   &&  /* Test for WP signature */
  72.          prefix.id[1] == 'W'  &&
  73.          prefix.id[2] == 'P'  &&
  74.          prefix.id[3] == 'C'  )
  75.     {
  76.         fprintf ( stderr,
  77.                   "%s is already a WordPerfect document\n",
  78.                   argv[1] );
  79.         unlink ( argv[2] );   /* delete the opened output file */
  80.         exit ( 6 );
  81.     }
  82.     else
  83.         rewind ( fin );
  84.  
  85.     /*---------------------------------------------------------
  86.      * So far, so good. Now, set up and write the prefix.
  87.      *-------------------------------------------------------*/
  88.  
  89.     prefix.id[0]       = -1;
  90.     prefix.id[1]       = 'W';
  91.     prefix.id[2]       = 'P';
  92.     prefix.id[3]       = 'C';
  93.     prefix.doc_start   = 76L;      /* length of prefix plus the
  94.                                      packets = 76 bytes.     */
  95.     prefix.prod_type   = 1;
  96.     prefix.file_type   = 0x0A;
  97.     prefix.maj_version = 0;
  98.     prefix.min_version = 1;      /* for WP5.0, set to 0 */
  99.     prefix.encrypted   = 0;      /* no encryption here */
  100.     prefix.filler      = 0;
  101.  
  102.     if (( fwrite ( &prefix, sizeof ( prefix ), 1, fout )) != 1 )
  103.     {
  104.         fprintf ( stderr, "Error writing to %s\n", argv[2] );
  105.         exit ( 7 );
  106.     }
  107.  
  108.     /*---------------------------------------------------------
  109.      * Now write out the additional prefix.
  110.      *-------------------------------------------------------*/
  111.     addl_prefix.packet_type = 0xFFFB;
  112.     addl_prefix.indices     = 5;
  113.     addl_prefix.index_size  = 50;
  114.     addl_prefix.next_block  = 0L;
  115.     fwrite ( &addl_prefix, sizeof ( addl_prefix ), 1, fout );
  116.  
  117.     /*---------------------------------------------------------
  118.      * Now write out the packet indices.
  119.      *-------------------------------------------------------*/
  120.               /* == Index to Packet 1 == */
  121.     packet.type           = 6;   /* 6 = document-specific data */
  122.     packet.length         = 8L;  /* points to 8 bytes of data  */
  123.     packet.data_offset    = 66L; /* data begins at byte 66     */
  124.     fwrite ( &packet, sizeof ( packet ), 1, fout );
  125.  
  126.               /* == Index to Packet 2 == */
  127.     packet.type           = 8;   /* 8 = graphics data          */
  128.     packet.length         = 2L;  /* points to 2 bytes of data  */
  129.     packet.data_offset    = 74L; /* data begins at byte 74,    */
  130.                                  /* i.e., right after data of  */
  131.                                  /* previous packet.           */
  132.     fwrite ( &packet, sizeof ( packet ), 1, fout );
  133.  
  134.               /* == Indices to Packets 3 & 4 == */
  135.     packet.type           = 0;   /* end of packets             */
  136.     packet.length         = 0L;
  137.     packet.data_offset    = 0L;
  138.     fwrite ( &packet, sizeof ( packet ), 1, fout );  /* #3 */
  139.     fwrite ( &packet, sizeof ( packet ), 1, fout );  /* #4 */
  140.  
  141.     /*---------------------------------------------------------
  142.      * At this point we have written out:
  143.      *      prefix                   = 16 bytes
  144.      *      additional prefix        = 10 bytes
  145.      *      4 packets @ 10 bytes     = 40 bytes
  146.      *                                 --
  147.      *      Total                      66 bytes.
  148.      * 
  149.      *  Hence, byte 66 (couting from zero) is the beginning 
  150.      *  of the data area. Note that this is the byte pointed 
  151.      *  to by packet #1's data_offset.
  152.      *-------------------------------------------------------*/
  153.  
  154.     /* the 8 bytes of data pointed to by packet 1
  155.         consist of four words:
  156.            word 0: a series of bit-field flags.
  157.                    when bit 4 (from 0) is set to 1,
  158.                    this tells WP to regenerate the document;
  159.                    all other bits shoud be set to 0.
  160.            word 1: redline character width
  161.                    use WP default of 124;
  162.            word 2: width of screen character
  163.                    use WP default of 120;
  164.            word 3: unused, set to 0.          */
  165.  
  166.     data_array[0] = 0x08;
  167.     data_array[1] = 124;
  168.     data_array[2] = 120;
  169.     data_array[3] = 0;
  170.     fwrite ( data_array, sizeof ( WORD ) * 4, 1, fout );
  171.  
  172.     /* the two bytes of data pointed to by packet 2
  173.        consist of one word:
  174.          if = 0, no graphics in this document;
  175.          if = 2, points to graphics data;  */
  176.  
  177.     data_array[0] = 0;
  178.     fwrite ( data_array, sizeof ( WORD ), 1, fout );
  179.  
  180.     /*---------------------------------------------------------
  181.      * Now write out the document.
  182.      *-------------------------------------------------------*/
  183.  
  184.     last_char_out = '\0'; /* make sure it's not a space
  185.                              to start with */
  186.  
  187.     for (;;)
  188.     {
  189.         int c;
  190.  
  191.         if (( c = fgetc ( fin )) == EOF )
  192.             break;
  193.  
  194.        /* Disable the following translation if you do NOT want
  195.           to have WordPerfect do the word-wrapping for the file.
  196.           Should be left alone for documents, but disabled
  197.           for columnar data, source code files, poetry, etc.
  198.  
  199.            Here's how it works:
  200.            0x0A (LF) is the hard return for WP. A line break
  201.                      here is mandatory.
  202.            0x0D (CR) is a soft return for WP. That is, one that
  203.                      can be moved around to accommodate word
  204.                      wrapping functions.                     */
  205.  
  206. #define CR 0x0D
  207. #define LF 0x0A
  208.  
  209.         if ( c == CR ) /* the start of a text CR/LF combination*/
  210.         {
  211.             c = fgetc ( fin );  /* get the next character */
  212.             if ( c != LF )      /* is it the LF we expect? */
  213.             {                   /* No!, so pass it all through */
  214.                 fputc ( CR, fout );
  215.                 last_char_out = fputc ( c, fout );
  216.             }
  217.             else            /* It was a CR/LF. It will be soft */
  218.             {               /*   if text follows. */
  219.                 c = fgetc ( fin );
  220.                 if ( isspace ( c )) /* followed by whitespace? */
  221.                 {
  222.                     fputc ( LF, fout ); /* yes, so write a hard*/
  223.                     last_char_out = fputc ( c, fout ); /*return*/
  224.                 }
  225.                 else
  226.                 {
  227.                     if ( last_char_out != ' ' ) /* No, so write*/
  228.                         fputc ( CR, fout );   /* a soft return.*/
  229.                     ungetc ( c, fin );        /* Put back that */
  230.                 }                             /* last character*/
  231.             }
  232.         }
  233.         else
  234.         {
  235.         /* Any translation of formatting data should go here */
  236.  
  237.         /* As an example, here is how ASCII characters with the 
  238.            8th bit set are translated. First, find out which WP 
  239.            character is the equivalent of the character being 
  240.            translated. Then specify it, by embedding the number 
  241.            of the character and the character set into a 4-byte 
  242.            escape sequence:
  243.  
  244.                             C0h char char-set C0h
  245.  
  246.            In this example, we translate the character for 1/2 
  247.            (ABh): which is character 17 in WP character set 4. 
  248.            Most books on WP gives the full list of translations.
  249.            So... */
  250.  
  251.            if ( c == 0xAB )
  252.            {
  253.                 fprintf ( fout, "%c%c%c%c", 
  254.                                   0xC0, 0x11, 0x04, 0xC0 );
  255.                 last_char_out = c;
  256.            }
  257.            else
  258.                 last_char_out = fputc ( c, fout );
  259.         }
  260.     }
  261.  
  262.     fclose ( fin );
  263.     fclose ( fout );
  264.  
  265.     exit (EXIT_SUCCESS); /* defined in stdlib.h--all went well */
  266. }